#!/usr/bin/python
# -*- coding: utf-8 -*-

# Copyright (C) 1994  Ling Li
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.


import gtk, gtk.gdk
from gtk import gdk
from gtk import *

import logging, re
from threading import Thread

from configuration import config_value
from utils import *

class LogView:

    __use_custom_status_font = False
    __status_font = ''

    __line_count = 0
    quit = False

    def __init__(self, main_window):
        def on_destroy(*args): self.quit = True
        self.__main_window = main_window
        self.__config = main_window.coralftp.config
        self.__xml = main_window.xml
        window = self.__xml.get_widget('main_window')
        window.connect('destroy', on_destroy)
        buffer = main_window.log_buffer
        self.__textview = self.__xml.get_widget('tv_log')
        self.__textview.set_buffer(buffer)

        color = config_value(self.__config, 'display', 'command_text_color')
        buffer.create_tag('log_command_text', foreground=color)
        self.__config.notify_add(
            'display', 'command_text_color',
            self.on_color_change, 'log_command_text')
        color = config_value(
            self.__config, 'display', 'left_ftp_reply_color')
        buffer.create_tag('log_left_reply_text', foreground=color)
        self.__config.notify_add(
            'display', 'left_ftp_reply_color',
            self.on_color_change, 'log_left_reply_text')
        color = config_value(
            self.__config, 'display', 'right_ftp_reply_color')
        buffer.create_tag('log_right_reply_text', foreground=color)        
        self.__config.notify_add(
            'display', 'right_ftp_reply_color',
            self.on_color_change, 'log_right_reply_text')
        color = config_value(self.__config, 'display', 'error_text_color')
        buffer.create_tag('log_error_text', foreground=color)
        self.__config.notify_add(
            'display', 'error_text_color',
            self.on_color_change, 'log_error_text')
        color = config_value(self.__config, 'display', 'misc_text_color')
        buffer.create_tag('log_misc_text', foreground=color)
        self.__config.notify_add(
            'display', 'misc_text_color',
            self.on_color_change, 'log_misc_text')
        color = config_value(
            self.__config, 'display', 'queue_complete_text_color')
        buffer.create_tag('log_queue_complete_text', foreground=color)
        self.__config.notify_add(
            'display', 'queue_complete_text_color',
            self.on_color_change, 'log_queue_complete_text')

        # setup fonts
        self.__use_custom_status_font = config_value(
            self.__config, 'display', 'use_custom_status_font')
        self.__status_font = config_value(
            self.__config, 'display', 'status_font')
        self.__change_font()
        self.__config.notify_add('display', 'use_custom_status_font',
                                 self.on_use_custom_status_font_change)
        self.__config.notify_add('display', 'status_font',
                                 self.on_status_font_change)

        # setup maxline
        self.__max_lines = config_value(
            self.__config, 'general', 'scrollback_buffer')
        self.__config.notify_add('general', 'scrollback_buffer',
                                 self.on_scrollback_buffer_change)

        self.__updater = LogViewUpdater(self)
        return

    def on_use_custom_status_font_change(self, config, id, value, *args):
        self.__use_custom_status_font = value.get_bool()
        self.__change_font()
        return

    def on_status_font_change(self, config, id, value, *args):
        self.__status_font = value.get_string()
        self.__change_font()
        return

    def __change_font(self):
        tagtable = self.__textview.get_buffer().get_tag_table()
        for tagname in ('log_command_text', 'log_left_reply_text',
                        'log_right_reply_text', 'log_error_text',
                        'log_misc_text', 'log_queue_complete_text'):
            tag = tagtable.lookup(tagname)
            if self.__use_custom_status_font:
                tag.set_property('font', self.__status_font)
            else:
                tag.set_property('font', None)
        return

    def on_color_change(self, config, id, value, tagname, *args):
        tagtable = self.__textview.get_buffer().get_tag_table()
        tag = tagtable.lookup(tagname)
        tag.set_property('foreground', value.get_string())
        return

    def on_scrollback_buffer_change(self, config, id, value, *args):
        self.__max_lines = value.get_int()
        return

    def on_insert_text(self, text, *args):
        buffer = self.__textview.get_buffer()
        self.__line_count = self.__line_count + string.count(text, '\n')
        delete = self.__line_count - self.__max_lines
        if delete > 0:
            start = buffer.get_start_iter()
            end = buffer.get_iter_at_line_offset(delete, 0)
            buffer.delete(start, end)
            self.__line_count = self.__line_count - delete
        return
        
    def __getattr__(self, name):
        if name == 'textview':
            return self.__textview
        elif name == 'log_buffer':
            return self.__textview.get_buffer()
        elif name == 'main_window':
            return self.__main_window
        elif name == 'updater':
            return self.__updater
        else:
            raise AttributeError, name

    def __call__(self, obj, type, msg):
        self.__updater(msg)

class LogViewUpdater:
    
    def __init__(self, log_view):
        self.__log_view = log_view
        self.__log_textview = log_view.textview
        self.__log_buffer = log_view.log_buffer
        return

    def __call__(self, msg):
        if self.__log_view.quit: return
        msg_type = 'log_misc_text'
        if msg.find('cmd') == 1:
            msg_type = 'log_command_text'
            msg = msg[6:]
        elif msg.find('resp') == 1:
            msg_type = 'log_right_reply_text'
            msg = msg[7:]
        elif msg.find('error') == 1:
            msg_type = 'log_error_text'
            msg = msg[7:]
        if msg:
            self.__log_view.on_insert_text(msg)
            iter = self.__log_buffer.get_end_iter()
            self.__log_buffer.insert_with_tags_by_name(iter, msg, msg_type)
            gobject.idle_add(self.scroll_to_end, self.__log_textview)
        return

    def scroll_to_end(self, textview):
        if self.__log_view.quit: return
        iter = textview.get_buffer().get_end_iter()
        textview.scroll_to_iter(iter, 0, True, 1, 0)
        return False
